package com.lix.controller.workflow;

import com.lix.auth.filter.TokenVerificationFilter;
import com.lix.base.BaseResult;
import com.lix.enums.BusinessStatusEnum;
import com.lix.service.workflow.IBusinessStatusService;
import com.lix.service.workflow.IProcessInstanceService;
import com.lix.utils.UserUtils;
import com.lix.vo.workflow.req.ProcInstReq;
import com.lix.vo.workflow.req.StartReq;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;

/**
 * 流程实例管理
 * @author lix
 */
@Api(tags = "流程实例管理")
@Slf4j
@RestController
@RequestMapping("/flow/instance")
public class ProcessInstanceController {

    @Autowired
    private IProcessInstanceService processInstanceService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private IBusinessStatusService businessStatusService;

    @Autowired
    private UserUtils userUtils;

    @ApiOperation(value = "提交申请，启动流程实例")
    @PostMapping("/start")
    public BaseResult start(@RequestBody StartReq req) {
        return processInstanceService.startProcess(req);
    }

    @ApiOperation("返回(撤回)申请")
    @DeleteMapping("/cancel/apply")
    public BaseResult cancelApply(@RequestParam String businessKey, @RequestParam String procInstId, @RequestParam(defaultValue = "返回【撤回】成功") String message) {
        return processInstanceService.cancel(businessKey, procInstId, message);
    }

    @ApiOperation("通过流程实例id获取申请表单组件名")
    @GetMapping("/form/name/{procInstId}")
    public BaseResult getFormName(@PathVariable String procInstId) {
        return processInstanceService.getFormNameByProcInstId(procInstId);
    }

    @ApiOperation("通过流程实例id获取任务办理历史记录")
    @GetMapping("/history/list") // ?procInstId=xxx
    public BaseResult getHistoryInfoList(@RequestParam String procInstId) {
        return processInstanceService.getHistoryInfoList(procInstId);
    }

    @ApiOperation("通过流程实例id获取历史流程图")
    @GetMapping("/history/image") // ?procInstId=xxx
    public void getHistoryProcessImage(@RequestParam String procInstId, HttpServletResponse response) {
        processInstanceService.getHistoryProcessImage(procInstId, response);
    }

    @ApiOperation("查询正在运行中的流程实例")
    @PostMapping("/list/running")
    public BaseResult getProcInstRunning(@RequestBody ProcInstReq req) {
        return processInstanceService.getProcInstListRunning(req);
    }

    @ApiOperation("挂起或激活流程实例")
    @PutMapping("/state/{procInstId}")
    public BaseResult updateProcInstState(@PathVariable String procInstId) {
        // 1. 查询指定流程实例的数据
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(procInstId)
                .singleResult();

        // 2. 判断当前流程实例的状态是否为：挂起（暂停）
        if (processInstance.isSuspended()) {
            // 如果状态是：挂起，将状态更新为：激活 (启动）
            runtimeService.activateProcessInstanceById(procInstId);
        } else {
            // 如果状态是：激活，将状态更新为：挂起（暂停）
            runtimeService.suspendProcessInstanceById(procInstId);
        }
        return BaseResult.ok();
    }

    @ApiOperation("作废流程实例，不会删除历史记录")
    @DeleteMapping("/{procInstId}")
    public BaseResult deleteProcInst(@PathVariable String procInstId) {
        // 1. 查询流程实例
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(procInstId).singleResult();

        if(processInstance == null) {
            return BaseResult.error("流程实例不存在");
        }

        // 2. 删除流程实例
        runtimeService.deleteProcessInstance(procInstId, userUtils.getUsername() + "作废了当前流程申请");

        // 3. 更新业务状态
        return businessStatusService.updateState(processInstance.getBusinessKey(), BusinessStatusEnum.INVALID);
    }

    @ApiOperation("查询已结束的流程实例")
    @PostMapping("/list/finish")
    public BaseResult getProcInstFinish(@RequestBody ProcInstReq req) {
        return processInstanceService.getProcInstFinish(req);
    }

    @ApiOperation("删除已结束流程实例和历史记录")
    @DeleteMapping("/history/{procInstId}")
    public BaseResult deleteProcInstAndHistory(@PathVariable String procInstId) {
        return processInstanceService.deleteProcInstAndHistory(procInstId);
    }
}
